package com.smedi.ismedi.progress.core.domain.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.*;
import com.deepoove.poi.data.style.BorderStyle;
import com.deepoove.poi.data.style.CellStyle;
import com.deepoove.poi.data.style.ParagraphStyle;
import com.deepoove.poi.data.style.Style;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.policy.TableRenderPolicy;
import com.smedi.ismedi.file.dto.request.SignatureRequest;
import com.smedi.ismedi.file.dto.response.FileInfoResponse;
import com.smedi.ismedi.file.feign.RemoteFileFeignApi;
import com.smedi.ismedi.progress.api.dto.response.*;
import com.smedi.ismedi.progress.core.application.command.ConstructionLogDownloadQuery;
import com.smedi.ismedi.progress.core.domain.aggregatemodel.*;
import com.smedi.ismedi.progress.core.domain.dto.FileQuery;
import com.smedi.ismedi.progress.core.domain.dto.ProjectBriefReportVo;
import com.smedi.ismedi.progress.core.domain.repository.FileRepository;
import com.smedi.ismedi.progress.core.domain.service.ExportExcelDomainService;
import com.smedi.ismedi.progress.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.progress.core.infrastructure.util.ExportFiles;
import com.smedi.ismedi.progress.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.progress.core.port.adapter.service.CallFileApiService;
import com.smedi.ismedi.web.starter.exception.LogicException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;


import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.smedi.ismedi.progress.core.infrastructure.constant.ConstantField.EngineeringLicenseHandlingEnum.*;

/**
 * 业务服务实体类
 *
 * @author xienannan
 * @date 2021/08/28
 */
@Slf4j
@Component
@AllArgsConstructor
public class ExportExcelDomainServiceImpl extends ExportFiles implements ExportExcelDomainService {
    private final static int PHOTO_PAGE_SIZE = 2;
    private final static double PHOTO_SIZE = 280.0;
    private final CallFileApiService callFileApiService;
    private final RemoteFileFeignApi remoteFileFeignApi;
    private final FileRepository fileRepository;
    private final AdapterConverter adapterConverter;

    @Override
    public ResponseEntity<byte[]> exportProgressMonthReport(List<ProgressReportMonthDetailAllResponse> list, int exportType) throws IOException {
        List<byte[]> pdfFileList = new ArrayList<>();
        Map<Integer, String> projectNameMap = new HashMap<>();
        int index = 0;
        for (ProgressReportMonthDetailAllResponse progressReportMonthDetailAllResponse : list) {
            log.info("准备数据写入word: {}", LocalDateTime.now());
            Map<String, Object> monthMap = new HashMap<>();
            ProgressReportMonthDetailResponse progressReportMainList = progressReportMonthDetailAllResponse.getProgressReportMainList();
            if (progressReportMainList == null) {
                throw LogicException.raise(CustomError.NO_DATA_FOUND);
            }
            projectNameMap.put(index++, progressReportMainList.getName());
            String statisticalTime;
            if (exportType == 1) {
                statisticalTime = progressReportMainList.getStatisticalStartTime().toString().substring(0, 7);
            } else {
                statisticalTime = progressReportMainList.getStatisticalStartTime().toString().substring(0, 10) + "~" + progressReportMainList.getStatisticalEndTime().toString().substring(0, 10);
            }
            //添加主要详情
            monthMap.put("projectName", progressReportMainList.getName());
            monthMap.put("statisticalTime", statisticalTime);
            monthMap.put("projectGeneralCompletion", progressReportMainList.getProjectGeneralCompletion());
            monthMap.put("progressLagMeasuresReason", progressReportMainList.getProgressLagMeasuresReason());
            monthMap.put("reportOutputValue", progressReportMainList.getReportOutputValue() == null ? 0.0 : progressReportMainList.getReportOutputValue().toString());
            monthMap.put("accumulationOutput", progressReportMainList.getAccumulationOutput() == null ? 0.0 : progressReportMainList.getAccumulationOutput().toString());
            monthMap.put("contractCost", progressReportMainList.getContractCost() == null ? 0.0 : progressReportMainList.getContractCost().toString());
            monthMap.put("outputValueIsShow", exportType == 1);
            monthMap.put("year", progressReportMainList.getStatisticalEndTime().getYear());
            monthMap.put("month", progressReportMainList.getStatisticalEndTime().getMonthValue());
            monthMap.put("recordYear", progressReportMainList.getRecordTime().getYear());
            monthMap.put("recordMonth", progressReportMainList.getRecordTime().getMonthValue());
            monthMap.put("recordDay", progressReportMainList.getRecordTime().getDayOfMonth());
            //一级任务列表
            List<TaskListResponse> firstTaskList = progressReportMonthDetailAllResponse.getFirstTaskList();
            //转换list对象
            List<TaskListExport> taskListExports = extendTaskList(firstTaskList, "图片 1.");
            //处理 显示的图片对应名称 关系  得到图片列表
            List<RowRenderData> firstPhotoList = extendTaskListPhoto(taskListExports);
            if (CollectionUtils.isNotEmpty(firstPhotoList)) {
                RowRenderData[] firstPhotoArr = firstPhotoList.toArray(new RowRenderData[0]);
                monthMap.put("firstPhotoList", Tables.of(firstPhotoArr).border(BorderStyle.builder().withType(XWPFTable.XWPFBorderType.NONE).build()).create());
                //monthMap.put("firstPhotoList",Tables.of(firstPhotoArr).border(BorderStyle.DEFAULT).create());
            }
            monthMap.put("firstTaskList", taskListExports);
            //里程碑列表
            List<MilestoneDetailResponse> milestoneList = progressReportMonthDetailAllResponse.getMilestoneList();
            List<MilestoneListExport> milestoneListExports = extendMilestoneList(milestoneList);
            List<RowRenderData> milestonePhotoList = extendMilestoneListPhoto(milestoneListExports);
            monthMap.put("milestoneList", milestoneListExports);
            if (CollectionUtils.isNotEmpty(milestonePhotoList)) {
                RowRenderData[] firstPhotoArr = milestonePhotoList.toArray(new RowRenderData[0]);
                monthMap.put("milestonePhotoList", Tables.of(firstPhotoArr).border(BorderStyle.builder().withType(XWPFTable.XWPFBorderType.NONE).build()).create());
                //monthMap.put("milestonePhotoList",Tables.of(firstPhotoArr).border(BorderStyle.DEFAULT).create());
            }
            //关键任务列表
            List<TaskListResponse> keyTaskList = progressReportMonthDetailAllResponse.getKeyTaskList();
            List<TaskListExport> keyTaskListExports = extendTaskList(keyTaskList, "图片 3.");
            List<RowRenderData> keyPhotoList = extendTaskListPhoto(keyTaskListExports);
            if (CollectionUtils.isNotEmpty(keyPhotoList)) {
                RowRenderData[] keyPhotoArr = keyPhotoList.toArray(new RowRenderData[0]);
                monthMap.put("keyPhotoList", Tables.of(keyPhotoArr).border(BorderStyle.builder().withType(XWPFTable.XWPFBorderType.NONE).build()).create());
                //monthMap.put("keyPhotoList", Tables.of(keyPhotoArr).border(BorderStyle.DEFAULT).create());
            }
            monthMap.put("keyTaskList", keyTaskListExports);
            System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");

            //循环列
            LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
            TableRenderPolicy tableRenderPolicy = new TableRenderPolicy();
            Configure config = Configure.builder()
                    .bind("firstTaskList", policy)
                    .bind("keyTaskList", policy)
                    .bind("milestoneList", policy)
                    .bind("milestonePhotoList", tableRenderPolicy)
                    .bind("firstPhotoList", tableRenderPolicy)
                    .bind("keyPhotoList", tableRenderPolicy)
                    .build();

            Resource resource = new ClassPathResource("fileTemplate/ProgressReportMonth.docx");

            InputStream inputStream = resource.getInputStream();

            XWPFTemplate template = XWPFTemplate.compile(inputStream, config).render(monthMap);
//            template.writeToFile("C:\\Users\\19037\\Desktop\\1.docx");
            log.info("写入word结束: {}", LocalDateTime.now());
            // 创建文件
            final File outputFile = File.createTempFile(IdUtil.simpleUUID(), ".docx");
            try (FileOutputStream outputStream = new FileOutputStream(outputFile); FileInputStream is = new FileInputStream(outputFile)) {
                template.write(outputStream);
                byte[] bytes = IOUtils.toByteArray(is);
                pdfFileList.add(bytes);
//                String uploadFileKey = callFileApiService.uploadFile(outputFile);
//                String signKey = callFileApiService.convertToPdf(uploadFileKey);
//                List<String> signKeyList = new ArrayList<>();
//                signKeyList.add(signKey);
//                List<com.smedi.ismedi.progress.core.domain.aggregatemodel.File> fileList = fileRepository.getFileList(FileQuery.builder().signKeys(signKeyList).build());
//                log.info("调用远程转换pdf结束: {}", LocalDateTime.now());
//                fileList.forEach(o->{
//                    pdfFileList.add( FileResponse.builder()
//                            .name(o.getName())
//                            .extName(o.getExtName())
//                            .signKey(o.getSignKey())
//                            .url(o.getUrlOut())
//                            .build());
//                });
            } catch (Exception e) {
                e.printStackTrace();
                log.error(e.getMessage());
            } finally {
//                Files.deleteIfExists(Paths.get(outputFile.getAbsolutePath()));
                template.close();
            }
        }
        if (pdfFileList.size() == 1) {
            byte[] bytes = pdfFileList.get(0);
            HttpHeaders headers = new HttpHeaders();
            String fileName = exportType == 1 ? projectNameMap.get(0)+ "月报.docx" : projectNameMap.get(0)+"周报.docx";
            headers.setContentType(MediaType.APPLICATION_STREAM_JSON);
            headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
            return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
            //直接导出pdf
////            FileResponse fileResponse = pdfFileList.get(0);
//
//            String projectName = projectNameMap.get(0);
//            URL url = new URL(fileResponse.getUrl());
//            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//            conn.setRequestMethod("GET");
//            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//            conn.setConnectTimeout(3 * 1000);
//            final ByteArrayOutputStream output = new ByteArrayOutputStream();
//            IOUtils.copy(conn.getInputStream(), output);
//
//            HttpHeaders headers = new HttpHeaders();
//            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//            String fileName = projectName + (exportType == 1 ? "-月报.pdf" : "-周报.pdf");
//            headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
//            return new ResponseEntity<>(output.toByteArray(), headers, HttpStatus.OK);
        } else {
//            return null;
            // 压缩
            return zipPdf(pdfFileList, exportType, projectNameMap);
        }

    }

    @Override
    public ResponseEntity<byte[]> projectBriefReportExport(List<ProjectBriefReportVo> projectBriefReportVos) throws IOException {
        List<FileResponse> pdfFileList = new ArrayList<>();
        Map<Integer, String> briefReportNameMap = new HashMap<>();
        int index = 0;
        for (ProjectBriefReportVo projectBriefReportVo : projectBriefReportVos) {
            Map<String, Object> map = new HashMap<>();
            List<ProjectBriefReportDetailExport> projectBriefReportDetailExports = new ArrayList<>();
            for (ProjectBriefReportDetail projectBriefReportDetail : projectBriefReportVo.getProjectBriefReportDetails()) {
                ProjectBriefReportDetailExport projectBriefReportDetailExport = new ProjectBriefReportDetailExport();
                projectBriefReportDetailExport.setBriefReportName(projectBriefReportDetail.getBriefReportName());
                projectBriefReportDetailExport.setProjectName(projectBriefReportDetail.getProjectName());
                projectBriefReportDetailExport.setExistQuestionPrecautions(projectBriefReportDetail.getExistQuestionPrecautions());
                projectBriefReportDetailExport.setId(projectBriefReportDetail.getId());
                projectBriefReportDetailExport.setMainCourtyard(projectBriefReportDetail.getMainCourtyard());
                projectBriefReportDetailExport.setMonthAllProgress(projectBriefReportDetail.getMonthAllProgress());
                projectBriefReportDetailExport.setNextMonthNode(projectBriefReportDetail.getNextMonthNode());
                projectBriefReportDetailExport.setStatus(projectBriefReportDetail.getStatus());
                projectBriefReportDetailExports.add(projectBriefReportDetailExport);
            }
            briefReportNameMap.put(index++, projectBriefReportVo.getBriefReportName());
            String date = projectBriefReportVo.getBriefReportName().substring(projectBriefReportVo.getBriefReportName().length() - 14);
            String title = projectBriefReportVo.getBriefReportName().substring(0, projectBriefReportVo.getBriefReportName().length() - 14);
            map.put("title", title);
            map.put("date", date);
            map.put("list", projectBriefReportDetailExports);
            map.put("remark", projectBriefReportVo.getRemarksInformation());
            System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
            LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
            Configure config = Configure.builder().bind("list", policy).build();

            Resource resource = new ClassPathResource("fileTemplate/ProjectBriefReport.docx");

            InputStream inputStream = resource.getInputStream();

            XWPFTemplate template = XWPFTemplate.compile(inputStream, config).render(map);
            // 创建文件
            final File outputFile = File.createTempFile(IdUtil.simpleUUID(), ".docx");
            try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
                template.write(outputStream);
                String uploadFileKey = callFileApiService.uploadFile(outputFile);
                String signKey = callFileApiService.convertToPdf(uploadFileKey);
                List<String> signKeyList = new ArrayList<>();
                signKeyList.add(signKey);
                List<com.smedi.ismedi.progress.core.domain.aggregatemodel.File> fileList = fileRepository.getFileList(FileQuery.builder().signKeys(signKeyList).build());
                fileList.forEach(o -> {
                    pdfFileList.add(FileResponse.builder()
                            .name(o.getName())
                            .extName(o.getExtName())
                            .signKey(o.getSignKey())
                            .url(o.getUrlOut())
                            .build());
                });
            } catch (Exception e) {
                e.printStackTrace();
                log.error(e.getMessage());
            } finally {
                Files.deleteIfExists(Paths.get(outputFile.getAbsolutePath()));
                template.close();
            }
        }

        if (pdfFileList.size() == 1) {
            //直接导出pdf
            FileResponse outputStream = pdfFileList.get(0);
            URL url = new URL(outputStream.getUrl());
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            conn.setConnectTimeout(3 * 1000);
            final ByteArrayOutputStream output = new ByteArrayOutputStream();
            IOUtils.copy(conn.getInputStream(), output);

            HttpHeaders headers = new HttpHeaders();
            String fileName = briefReportNameMap.get(0) + ".pdf";
            headers.setContentType(MediaType.APPLICATION_STREAM_JSON);
            headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
            return new ResponseEntity<>(output.toByteArray(), headers, HttpStatus.OK);
        } else {
            //压缩
            return zipPdfBriefReport(pdfFileList, briefReportNameMap);
        }

    }

    @Override
    public ResponseEntity<byte[]> constructionLogExport(ConstructionLogDetail constructionLogDetail) throws IOException {
        List<ProgressFile> pdfFileList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
//        map.put("projectName", new TextRenderData(constructionLogDetail.getProjectName(),Style.builder().buildFontFamily("SimSun").buildFontSize(9).build()));
        map.put("projectName", Texts.of(constructionLogDetail.getProjectName()).fontFamily("SimSun").fontSize(9).create());
        map.put("logDate",Texts.of(constructionLogDetail.getLogDate().toString()).fontFamily("SimSun").fontSize(9).create());
        map.put("weather",Texts.of( constructionLogDetail.getWeather()).fontFamily("SimSun").fontSize(9).create());
        map.put("recordUser", Texts.of(constructionLogDetail.getRecordUser()).fontFamily("SimSun").fontSize(9).create());
        String date = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(constructionLogDetail.getRecordTime());
        map.put("recordTime",Texts.of(date).fontFamily("SimSun").fontSize(9).create());
        map.put("projectManager",constructionLogDetail.getReadingStatus() == 2 ? Texts.of(StringUtils.isEmpty(constructionLogDetail.getProjectManager())?"":constructionLogDetail.getProjectManager()).fontFamily("SimSun").fontSize(9).create() : "");
        map.put("materialsRecord", constructionLogDetail.getMaterialsRecord());
        map.put("mechanicalArrange", constructionLogDetail.getMechanicalArrange());
        map.put("accidentDealMethods", constructionLogDetail.getAccidentDealMethods());
        map.put("otherSpecialSituation", constructionLogDetail.getOtherSpecialSituation());
        //        //pdf处理内容不换行
//        constructionLogDetail.getConstructionLogContents().forEach(v->{
//            int length = v.getSegmentPosition().length();
//            if(length > 20) {
//                v.setSegmentPosition(v.getSegmentPosition().replaceAll("(.{20})", "$1\n"));
//            }
//        });
        map.put("constructionLogContents", constructionLogDetail.getConstructionLogContents());

        List<RowRenderData> pictureRenderDatas = extendConstructionLogPhoto(constructionLogDetail.getFile());

        if (CollectionUtils.isNotEmpty(pictureRenderDatas)) {
            RowRenderData[] PhotoArr = pictureRenderDatas.toArray(new RowRenderData[0]);
            map.put("photo", Tables.of(PhotoArr).border(BorderStyle.builder().withType(XWPFTable.XWPFBorderType.NONE).build()).create());
        }
        System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");

        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder().bind("constructionLogContents", policy).build();

        Resource resource = new ClassPathResource("fileTemplate/ConstructionLog1.docx");

        InputStream inputStream = resource.getInputStream();

        XWPFTemplate template = XWPFTemplate.compile(inputStream, config).render(map);

        //template.writeToFile("C:\\Users\\EDY\\Desktop\\1.docx");

        // 创建文件
        final File outputFile = File.createTempFile(IdUtil.simpleUUID(), ".docx");
        try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
            template.write(outputStream);
            String uploadFileKey = callFileApiService.uploadFile(outputFile);
              //支持签章
            String signKey = callFileApiService.convertToPdfKey(uploadFileKey);
//            String signKey = callFileApiService.convertToPdf(uploadFileKey);
            List<String> signKeyList = new ArrayList<>();
            //获取人员签章
            try{
                if (constructionLogDetail.getEmployeeNum()!=null && constructionLogDetail.getReadingStatus()==2) {
                    List<SignatureRequest> signatureRequests = new ArrayList<>();
                    SignatureRequest signatureRequest = new SignatureRequest();
                    signatureRequest.setFileKey(signKey);
                    signatureRequest.setWorkerId(Long.parseLong(constructionLogDetail.getEmployeeNum()));
                    signatureRequest.setSignLocation("No_pon");
                    signatureRequests.add(signatureRequest);
                    FileInfoResponse fileInfoResponse = remoteFileFeignApi.postSignatures(signatureRequests).getData();
                    if(ObjectUtils.isNull(fileInfoResponse)|| fileInfoResponse.getSignKey() == null){
                        signKeyList.add(signKey);
                    }else{
                        signKeyList.add(fileInfoResponse.getSignKey());
                    }
                }else{
                    signKeyList.add(signKey);
                }
            }catch (Exception e){
                log.info("施工日志导出，获取人员签章报错，报错信息："+e.getMessage());
            }
            List<com.smedi.ismedi.progress.core.domain.aggregatemodel.File> fileList = fileRepository.getFileList(FileQuery.builder().signKeys(signKeyList).build());
            fileList.forEach(o -> {
                pdfFileList.add(ProgressFile.builder()
                        .name(o.getName())
                        .extName(o.getExtName())
                        .signKey(o.getSignKey())
                        .url(o.getUrlOut())
                        .build());
            });
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        } finally {
            Files.deleteIfExists(Paths.get(outputFile.getAbsolutePath()));
            template.close();
        }


        //直接导出pdf
        ProgressFile outputStream = pdfFileList.get(0);
        URL url = new URL(outputStream.getUrl());
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        conn.setConnectTimeout(3 * 1000);
        final ByteArrayOutputStream output = new ByteArrayOutputStream();
        IOUtils.copy(conn.getInputStream(), output);

        HttpHeaders headers = new HttpHeaders();
        String fileName = constructionLogDetail.getProjectName()+ constructionLogDetail.getLogDate() + ".pdf";
        headers.setContentType(MediaType.APPLICATION_STREAM_JSON);
        headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
        return new ResponseEntity<>(output.toByteArray(), headers, HttpStatus.OK);

    }

    private List<RowRenderData> extendConstructionLogPhoto(List<ProgressFile> files) {
        List<Map<String, Object>> pictureRenderDatas = new ArrayList<>();
        List<RowRenderData> rowRenderDataList = new ArrayList<>();

        for (ProgressFile file : files) {
            Map<String, Object> m = new HashMap<>();
            if (StringUtils.isNotBlank(file.getAliasName())) {
                m.put("name",Texts.of(file.getAliasName()).fontFamily("SimSun").fontSize(9).create() );
            } else {
                m.put("name",Texts.of(file.getName().substring(0,file.getName().length()-4)).fontFamily("SimSun").fontSize(9).create() );
            }
            //加进照片列表
            photoSize(file.getUrl(), m);
            pictureRenderDatas.add(m);
        }
        //数据分页，一行三张，写入到行对象
        limitPhotoData(rowRenderDataList, pictureRenderDatas);

        return rowRenderDataList;
    }

    @Override
    public ResponseEntity<byte[]> downloadBySignKeys(ConstructionLogDownloadQuery constructionLogDownloadQuery) {
        List<com.smedi.ismedi.progress.core.domain.aggregatemodel.File> fileList = fileRepository.getFileList(FileQuery.builder().signKeys(constructionLogDownloadQuery.getSignKeys()).build());
        List<ProgressFile> fileResponses = new ArrayList<>();
        fileList.forEach(o -> {
            fileResponses.add(ProgressFile.builder()
                    .name(o.getName())
                    .extName(o.getExtName())
                    .signKey(o.getSignKey())
                    .url(o.getUrlOut())
                    .build());
        });
        return zipPdfConstructionLog(fileResponses);
    }

    @Override
    public ResponseEntity<byte[]> engineeringReportExport(EngineeringReportDetail engineeringReportDetail, String mainCourtyard, Long type,Long exportType) throws IOException {
        List<ProgressFile> pdfFileList = new ArrayList<>();

        Map<String, Object> map = new HashMap<>();
        map.put("projectName", engineeringReportDetail.getProjectName());
        map.put("mainCourtyard", mainCourtyard);
        map.put("reportPeriodsNumber", engineeringReportDetail.getReportPeriodsNumber());
        map.put("year", engineeringReportDetail.getRecordTime().getYear());
        map.put("month", engineeringReportDetail.getRecordTime().getMonthValue());
        map.put("day", engineeringReportDetail.getRecordTime().getDayOfMonth());
        map.put("statisticalStartTime", engineeringReportDetail.getStatisticalStartTime());
        map.put("statisticalEndTime", engineeringReportDetail.getStatisticalEndTime());
        map.put("recordUser", engineeringReportDetail.getRecordUser());
        map.put("projectOverview", engineeringReportDetail.getProjectOverview());
        map.put("contractCost", engineeringReportDetail.getContractCost());
        map.put("epcTypeMeaning", engineeringReportDetail.getEpcTypeMeaning());
        map.put("durationTarget", engineeringReportDetail.getDurationTarget());
        map.put("buildUnit", engineeringReportDetail.getBuildUnit());
        map.put("supervisionUnit", engineeringReportDetail.getSupervisionUnit());
        map.put("epcUnit", engineeringReportDetail.getEpcUnit());
        map.put("survey", engineeringReportDetail.getSurvey());
        map.put("design", engineeringReportDetail.getDesign());
        map.put("equipmentPurchaseSituation", engineeringReportDetail.getEquipmentPurchaseSituation());
        map.put("projectGeneralCompletion", engineeringReportDetail.getProjectGeneralCompletion());
        map.put("progressLagMeasuresReason", engineeringReportDetail.getProgressLagMeasuresReason());
        map.put("nextMonthWorkPlan", engineeringReportDetail.getNextMonthWorkPlan());
        map.put("engineeringQuality", engineeringReportDetail.getEngineeringQuality());
        map.put("safeCivilizedConstruction", engineeringReportDetail.getSafeCivilizedConstruction());
        map.put("accumulationOutput", engineeringReportDetail.getAccumulationOutput() == null ? 0 : engineeringReportDetail.getAccumulationOutput());
        map.put("collection", engineeringReportDetail.getCollection() == null ? 0 : engineeringReportDetail.getCollection());
        map.put("problemsPrecautions", engineeringReportDetail.getProblemsPrecautions());

        List<EngineeringImportantNodePlan> nodePlans = engineeringReportDetail.getEngineeringImportantNodePlans();
        final int[] i = {1};
        nodePlans.forEach(v -> {
            v.setId((long) i[0]);
            i[0]++;
        });

        map.put("EngineeringImportantNodePlan", nodePlans);
        List<EngineeringConstructionCompletionExport> completionExport = adapterConverter.engineeringConstructionCompletionsToEngineeringConstructionCompletionsExport(engineeringReportDetail.getEngineeringConstructionCompletions());
//        //处理图片名字
//        this.extentName(completionExport);
        map.put("EngineeringConstructionCompletion", completionExport);
        //处理 显示的图片对应名称 关系  得到图片列表
        List<RowRenderData> completionPhotos = extendCompletionExportPhoto(completionExport);
        if (CollectionUtils.isNotEmpty(completionPhotos)) {
            RowRenderData[] PhotoArr = completionPhotos.toArray(new RowRenderData[0]);
            map.put("progressPhotos", Tables.of(PhotoArr).border(BorderStyle.builder().withType(XWPFTable.XWPFBorderType.NONE).build()).create());
        }

        System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
        //循环列
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        TableRenderPolicy tableRenderPolicy = new TableRenderPolicy();
        Configure config = Configure.builder()
                .bind("EngineeringConstructionCompletion", policy)
                .bind("EngineeringImportantNodePlan", policy)
                .bind("progressPhotos", tableRenderPolicy)
                .build();
        Resource resource = null;
        if (type == 2) {
            resource = new ClassPathResource("fileTemplate/EngineeringMonthReport.docx");
        } else {
            resource = new ClassPathResource("fileTemplate/EngineeringWeekReport.docx");
        }

        InputStream inputStream = resource.getInputStream();

        XWPFTemplate template = XWPFTemplate.compile(inputStream, config).render(map);
//        template.writeToFile("C:\\Users\\19037\\Desktop\\1.docx");

        // 创建文件
        final File outputFile = File.createTempFile(IdUtil.simpleUUID(), ".docx");
        try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
            template.write(outputStream);
            String uploadFileKey = callFileApiService.uploadFile(outputFile);
            List<String> signKeyList = new ArrayList<>();
            signKeyList.add(uploadFileKey);
            List<com.smedi.ismedi.progress.core.domain.aggregatemodel.File> fileList = fileRepository.getFileList(FileQuery.builder().signKeys(signKeyList).build());
            fileList.forEach(o -> {
                pdfFileList.add(ProgressFile.builder()
                        .name(o.getName())
                        .extName(o.getExtName())
                        .signKey(o.getSignKey())
                        .url(o.getUrlOut())
                        .build());
            });
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        } finally {
            Files.deleteIfExists(Paths.get(outputFile.getAbsolutePath()));
            template.close();
        }
        if(exportType == 1){
            //直接导出word
            ProgressFile outputStream = pdfFileList.get(0);
            URL url = new URL(outputStream.getUrl());
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            conn.setConnectTimeout(3 * 1000);
            final ByteArrayOutputStream output = new ByteArrayOutputStream();
            IOUtils.copy(conn.getInputStream(), output);

            HttpHeaders headers = new HttpHeaders();
            String fileName = engineeringReportDetail.getProjectName()+ ".docx";
            headers.setContentType(MediaType.APPLICATION_STREAM_JSON);
            headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            return new ResponseEntity<>(output.toByteArray(), headers, HttpStatus.OK);
        }else{
            List<EngineeringLicenseFile> license = engineeringReportDetail.getLicense();
            List<EngineeringLicenseFile> zipFile = new ArrayList<>();
            //把pdf  也放进去  统一处理
            zipFile.add(EngineeringLicenseFile.builder().licenseName(engineeringReportDetail.getProjectName() + (type == 1 ? "工程周报" : "工程月报")).file(pdfFileList).build());
            //把许可证 信息一一对应
            if (CollectionUtils.isNotEmpty(license)) {
                license.forEach(v -> {
                    String name;
                    if (CANTEEN_PERMIT.name().equals(v.getLicenseName())) {
                        name = "食堂许可证";
                    } else if (PLANNING_PERMIT.name().equals(v.getLicenseName())) {
                        name = "规划许可证（含用地、工程规划）";
                    } else if (EIA_REPORT.name().equals(v.getLicenseName())) {
                        name = "环评报告";
                    } else if (INSURANCE_PROCEDURES.name().equals(v.getLicenseName())) {
                        name = "保险手续";
                    } else if (QUALITY_PROCEDURES.name().equals(v.getLicenseName())) {
                        name = "质安监手续";
                    } else {
                        name = "施工许可证";
                    }
                    zipFile.add(EngineeringLicenseFile.builder().licenseName(name).file(v.getFile()).build());
                });
            }
            return zipEngineeringFile(zipFile);
        }
    }

    private ResponseEntity<byte[]> zipEngineeringFile(List<EngineeringLicenseFile> zipFile) {
        ZipOutputStream zos = null;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            int i= 0;
            zos = new ZipOutputStream(byteArrayOutputStream);
            for (EngineeringLicenseFile engineeringLicenseFile : zipFile) {
                if (engineeringLicenseFile.getFile()!=null) {
                    for (ProgressFile file : engineeringLicenseFile.getFile()) {
                        URL url = new URL(file.getUrl());
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                        conn.setRequestMethod("GET");
                        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
                        conn.setConnectTimeout(3 * 1000);
                        final ByteArrayOutputStream output = new ByteArrayOutputStream();
                        IOUtils.copy(conn.getInputStream(), output);
                        if (i==0){
                            zos.putNextEntry(new ZipEntry(engineeringLicenseFile.getLicenseName() + "." + file.getExtName()));
                        }else{
                            zos.putNextEntry(new ZipEntry(engineeringLicenseFile.getLicenseName()+"(" +i+ ")" + "." + file.getExtName()));
                        }
                        i++;
                        byte[] excelStream = output.toByteArray();
                        zos.write(excelStream);
                        zos.closeEntry();
                        zos.flush();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        } finally {
            try {
                assert zos != null;
                zos.flush();
                zos.close();
                byteArrayOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_STREAM_JSON);
        String fileName = "施工日志.zip";
        headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
        return new ResponseEntity<>(byteArrayOutputStream.toByteArray(), headers, HttpStatus.OK);
    }

//    //给工程完成情况 的照片名赋值
//    private void extentName(List<EngineeringConstructionCompletionExport> completionExports) {
//        Double firstTaskNum = 1.0;
//        DecimalFormat df = new DecimalFormat("0.0");
//        //名字拼接 赋值
//        for (EngineeringConstructionCompletionExport completionExport : completionExports) {
//            //根据每个对象图片的个数  设置图片名称 用 ， 隔开
//            if (CollectionUtils.isNotEmpty(completionExport.getProgressPhotos())) {
//                String photoEnd = "";
//                for (int i = 0; i < completionExport.getProgressPhotos().size(); i++) {
//                    String photo = "图片";
//                    firstTaskNum += 0.1;
//                    photo = photo + df.format(firstTaskNum);
//                    if (i < completionExport.getProgressPhotos().size() - 1) {
//                        photoEnd = photoEnd + photo.concat(",");
//                    } else {
//                        photoEnd = photoEnd + photo;
//                    }
//                }
//                completionExport.setPhoto(photoEnd);
//            }
//        }
//    }


    private List<RowRenderData> extendCompletionExportPhoto(List<EngineeringConstructionCompletionExport> completionExports) {
        List<Map<String, Object>> pictureRenderDatas = new ArrayList<>();
        List<RowRenderData> rowRenderDataList = new ArrayList<>();
        //照片排版
        for (EngineeringConstructionCompletionExport completionExport : completionExports) {
//            String[] photoName = {};
//            int i = 0;
//            //图片数大于1 拆分名字
            if (completionExport.getProgressPhotos() != null) {
//                if (completionExport.getProgressPhotos().size() > 1) {
//                    photoName = completionExport.getPhoto().split(",");
//                }
                for (ProgressFile file : completionExport.getProgressPhotos()) {
                    Map<String, Object> m = new HashMap<>();
                    m.put("name", file.getName().substring(0, file.getName().length() - 4));
//                    if (photoName.length > 0) {
//                        m.put("name", completionExport.getOneTaskName() + photoName[i++]);
//                    } else {
//                        m.put("name", completionExport.getOneTaskName() + completionExport.getPhoto());
//                    }
                    //加进照片列表
                    log.info("执行前");
                    photoSize(file.getUrl(), m);
                    log.info("执行后");
                    pictureRenderDatas.add(m);
                }
            }
        }
        //数据分页，一行五张，写入到行对象
        limitPhotoData(rowRenderDataList, pictureRenderDatas);

        return rowRenderDataList;
    }

    private ResponseEntity<byte[]> zipPdfConstructionLog(List<ProgressFile> pdfFileList) {
        ZipOutputStream zos = null;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            zos = new ZipOutputStream(byteArrayOutputStream);
            for (ProgressFile fileResponse : pdfFileList) {
                URL url = new URL(fileResponse.getUrl());
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
                conn.setConnectTimeout(3 * 1000);
                final ByteArrayOutputStream output = new ByteArrayOutputStream();
                IOUtils.copy(conn.getInputStream(), output);
                zos.putNextEntry(new ZipEntry(fileResponse.getName()));
                byte[] excelStream = output.toByteArray();
                zos.write(excelStream);
                zos.closeEntry();
                zos.flush();

            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        } finally {
            try {
                assert zos != null;
                zos.flush();
                zos.close();
                byteArrayOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_STREAM_JSON);
        String fileName = "工程报告.zip";
        headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
        return new ResponseEntity<>(byteArrayOutputStream.toByteArray(), headers, HttpStatus.OK);
    }

    public List<TaskListExport> extendTaskList(List<TaskListResponse> TaskList, String name) {
        List<TaskListExport> taskListExports = new ArrayList<>(TaskList.size());
//        Double firstTaskNum = 1.0;
//        DecimalFormat df = new DecimalFormat("0.0");
        //转换对象
        for (TaskListResponse taskListResponse : TaskList) {
            TaskListExport taskListExport = new TaskListExport();
            taskListExport.setNamePrefix(taskListResponse.getNamePrefix());
            taskListExport.setName(taskListResponse.getName());
            taskListExport.setLagTime(taskListResponse.getLagTime());
            taskListExport.setPercentage(taskListResponse.getPercentage() + "%");
            taskListExport.setPhotoFile(taskListResponse.getPhotoFile());
            taskListExport.setRealEndTime(taskListResponse.getRealEndTime());
            taskListExport.setScheduleStartTime(taskListResponse.getScheduleStartTime());
            taskListExport.setScheduleEndTime(taskListResponse.getScheduleEndTime());
            taskListExport.setRealStartTime(taskListResponse.getRealStartTime());
            taskListExport.setStatus(taskListResponse.getStatus());
//            //根据每个对象图片的个数  设置图片名称 用 ， 隔开
//            if (CollectionUtils.isNotEmpty(taskListResponse.getPhotoFile())) {
//                String photoEnd = "";
//                for (int i = 0; i < taskListResponse.getPhotoFile().size(); i++) {
//                    String photo = name;
//                    firstTaskNum += 0.1;
//                    photo = photo + df.format(firstTaskNum);
//                    if (i < taskListResponse.getPhotoFile().size() - 1) {
//                        photoEnd = photoEnd + photo.concat(",");
//                    } else {
//                        photoEnd = photoEnd + photo;
//                    }
//                }
//                taskListExport.setPhotoName(photoEnd);
//            }
            taskListExports.add(taskListExport);
        }
        return taskListExports;
    }

    public List<RowRenderData> extendTaskListPhoto(List<TaskListExport> taskListExports) throws IOException {
        List<Map<String, Object>> pictureRenderDatas = new ArrayList<>();
        List<RowRenderData> rowRenderDataList = new ArrayList<>();
        for (TaskListExport taskListExport : taskListExports) {
//            String[] photoName = {};
//            int i = 0;
//            //图片数大于1 拆分名字
            if (taskListExport.getPhotoFile() != null) {
//                if (taskListExport.getPhotoFile().size() > 1) {
//                    photoName = taskListExport.getPhotoName().split(",");
//                }
                for (FileResponse fileResponse : taskListExport.getPhotoFile()) {
                    Map<String, Object> m = new HashMap<>();
                    m.put("name", fileResponse.getName().substring(0, fileResponse.getName().length() - 4));
//                        URL url = new URL(fileResponse.getUrl());
//                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//                        conn.setRequestProperty("User-Agent", "Mozilla/4.76");
//                        InputStream is = conn.getInputStream();
//                        BufferedImage img = ImageIO.read(is);
//                        int high = img.getHeight();
//                        int width = img.getWidth();
//                        int max = Math.max(width, high);
//                        high = (high * PHOTO_SIZE) / max;
//                        width = (width * PHOTO_SIZE) / max;
//
//                    m.put("picture",Pictures.ofUrl(fileResponse.getUrl(), PictureType.JPEG).size(width,high).create());
                    //加进照片列表
                    log.info("执行前");
                    photoSize(fileResponse.getUrl(), m);
                    log.info("执行后");
                    pictureRenderDatas.add(m);
                }
            }
        }
        //数据分页，一行五张，写入到行对象
        limitPhotoData(rowRenderDataList, pictureRenderDatas);

        return rowRenderDataList;
    }

    public List<RowRenderData> extendMilestoneListPhoto(List<MilestoneListExport> taskListExports) throws IOException {
        List<Map<String, Object>> pictureRenderData = new ArrayList<>();
        List<RowRenderData> rowRenderDataList = new ArrayList<>();
        for (MilestoneListExport milestoneListExport : taskListExports) {
//            String[] photoName = {};
//            int i = 0;
            if (milestoneListExport.getPhotoFile() != null) {
//                if (milestoneListExport.getPhotoFile().size() > 1) {
//                    photoName = milestoneListExport.getPhotoName().split(",");
//                }
                for (FileResponse fileResponse : milestoneListExport.getPhotoFile()) {
                    Map<String, Object> m = new HashMap<>();
                    m.put("name", fileResponse.getName().substring(0, fileResponse.getName().length() - 4));
                    //设置缩放图片
                    log.info("执行前");
                    photoSize(fileResponse.getUrl(), m);
                    log.info("执行后");
                    pictureRenderData.add(m);
                }
            }
        }
        log.info("循环完");
        //数据分页，一行五张，写入到行对象
        limitPhotoData(rowRenderDataList, pictureRenderData);
        return rowRenderDataList;
    }

    /**
     * 比例缩放图片方法
     *
     * @param url
     * @param m
     * @return void
     * @date 2022/11/11 15:22
     */
    public void photoSize(String url, Map<String, Object> m) {
        try {
            URL s = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) s.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            conn.setConnectTimeout(3 * 1000);
            InputStream is = conn.getInputStream();
            //[BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]  加了jar 包   本地没问题  线上 还是会报网络错误
            BufferedImage img = ImageIO.read(is);
            conn.disconnect();
            is.close();
            log.info("判断前");
            //避免出现损坏图片 而 报空指针
            if (img == null || "null".equals(img) || "".equals(img)) {
                m.put("picture", Pictures.ofUrl(url, PictureType.JPEG).size((int) PHOTO_SIZE, (int) PHOTO_SIZE).create());
                log.error("图片类型不兼容 or 已损坏！");
                return;
            }
            //long high = img.getHeight();
            int width = img.getWidth();
            //int max = Math.max(width, high);
            long high = Math.round((PHOTO_SIZE / width) * img.getHeight());
            log.info("判断后width：{}，high：{}", width, high);
            m.put("picture", Pictures.ofUrl(url, PictureType.JPEG).size((int) PHOTO_SIZE, Math.toIntExact(high)).create());
        } catch (IOException e) {
            e.printStackTrace();
            log.error("图片处理发生异常！");
        }
    }

    public List<MilestoneListExport> extendMilestoneList(List<MilestoneDetailResponse> milestoneList) {
        List<MilestoneListExport> milestoneListExports = new ArrayList<>(milestoneList.size());
//        Double firstTaskNum = 1.0;
//        DecimalFormat df = new DecimalFormat("0.0");
        for (MilestoneDetailResponse milestoneDetailResponse : milestoneList) {
            MilestoneListExport milestoneListExport = new MilestoneListExport();
            milestoneListExport.setNamePrefix(milestoneDetailResponse.getNamePrefix());
            milestoneListExport.setName(milestoneDetailResponse.getName());
            milestoneListExport.setLagTime(Long.valueOf(milestoneDetailResponse.getLagTime()));
            milestoneListExport.setPhotoFile(milestoneDetailResponse.getPhotoFile());
            milestoneListExport.setCompletion(milestoneDetailResponse.getCompletion());
            milestoneListExport.setRealEndTime(milestoneDetailResponse.getRealEndTime());
            milestoneListExport.setScheduleEndTime(milestoneDetailResponse.getScheduleEndTime());
            milestoneListExport.setStatus(milestoneDetailResponse.getStatus() != null ? Long.valueOf(milestoneDetailResponse.getStatus()) : null);
//            if (CollectionUtils.isNotEmpty(milestoneDetailResponse.getPhotoFile())) {
//                String photoEnd = "";
//                for (int i = 0; i < milestoneDetailResponse.getPhotoFile().size(); i++) {
//                    String photo = "图片 2.";
//                    firstTaskNum += 0.1;
//                    photo = photo + df.format(firstTaskNum);
//                    if (i < milestoneDetailResponse.getPhotoFile().size() - 1) {
//                        photoEnd = photoEnd + photo.concat(",");
//                    } else {
//                        photoEnd = photoEnd + photo;
//                    }
//                }
//                milestoneListExport.setPhotoName(photoEnd);
//            }
            milestoneListExports.add(milestoneListExport);
        }
        return milestoneListExports;
    }

    /**
     * 数据分页，一行五张，写入到行对象
     *
     * @param rowRenderDataList  行对象
     * @param pictureRenderDatas 照片、标题对象
     */
    private void limitPhotoData(List<RowRenderData> rowRenderDataList, List<Map<String, Object>> pictureRenderDatas) {
        if (pictureRenderDatas.isEmpty()) {
            return;
        }
        int total = pictureRenderDatas.size();
        int pageNum = (total - 1) / PHOTO_PAGE_SIZE + 1;
        for (int pageNo = 0; pageNo < pageNum; pageNo++) {
            //五张一组
            List<Map<String, Object>> subList = pictureRenderDatas.stream().skip(pageNo * PHOTO_PAGE_SIZE).limit(PHOTO_PAGE_SIZE).
                    collect(Collectors.toList());
            //构建行对象
            RowRenderData rowRenderData = new RowRenderData();
            for (Map<String, Object> map : subList) {
                //添加照片列
                buildCell(rowRenderData, map);
            }
            for (int i = 0; i < PHOTO_PAGE_SIZE - subList.size(); i++) {
                //添加空列
                rowRenderData.addCell(new CellRenderData());
            }
            rowRenderDataList.add(rowRenderData);
        }
    }

    /**
     * 构建单元格中的数据
     *
     * @param rowRenderData 行对象
     * @param mapData       单元格数据（图片、文字）
     */
    private void buildCell(RowRenderData rowRenderData, Map<String, Object> mapData) {
        CellRenderData cellRenderData = new CellRenderData();
        ParagraphRenderData paragraphRenderData = new ParagraphRenderData();
        ParagraphStyle paragraphStyle = new ParagraphStyle();
        CellStyle cellStyle = new CellStyle();
        cellStyle.setVertAlign(XWPFTableCell.XWPFVertAlign.CENTER);

        TextRenderData textRenderData = new TextRenderData();
        textRenderData.setText("   " + mapData.get("name"));
        Style style = new Style();
        style.setVertAlign("CENTER");
        style.setFontSize(9);
        style.setFontFamily("SimSun");
        textRenderData.setStyle(style);

        paragraphStyle.setIndentLeftChars(-0.1);
        paragraphStyle.setIndentHangingChars(-0.1);
        paragraphStyle.setIndentFirstLineChars(0.0);
        paragraphStyle.setKeepLines(true);
        paragraphStyle.setSpacingBeforeLines(0.0);
        paragraphStyle.setSpacingAfterLines(0.0);
        paragraphStyle.setAlign(ParagraphAlignment.CENTER);
        paragraphRenderData.setParagraphStyle(paragraphStyle);


        paragraphRenderData.addPicture((PictureRenderData) mapData.get("picture"));
        paragraphRenderData.addText("\n\n" + textRenderData);


        cellRenderData.addParagraph(paragraphRenderData);
        cellRenderData.setCellStyle(cellStyle);

        rowRenderData.addCell(cellRenderData);
    }

    private ResponseEntity<byte[]> zipPdf(List<byte[]> pdfFileList, int exportType, Map<Integer, String> projectNameMap) {
        //通过ZipOutputStream定义要写入的对象
        ZipOutputStream zos = null;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            int i = 0;
            zos = new ZipOutputStream(byteArrayOutputStream);
            for (byte[] fileResponse : pdfFileList) {
//                URL url = new URL(fileResponse.getUrl());
//                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//                conn.setRequestMethod("GET");
//                conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//                conn.setConnectTimeout(3 * 1000);
//                final ByteArrayOutputStream output = new ByteArrayOutputStream();
//                IOUtils.copy(conn.getInputStream(), output);
                zos.putNextEntry(new ZipEntry(projectNameMap.get(i) + "-" + (i + 1) + ".docx"));
//                byte[] excelStream= output.toByteArray();
                zos.write(fileResponse);
                i++;
                zos.closeEntry();
                zos.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        } finally {
            try {
                assert zos != null;
                zos.flush();
                zos.close();
                byteArrayOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_STREAM_JSON);
        String fileName = exportType == 1 ? "月报.zip" : "周报.zip";
        headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
        return new ResponseEntity<>(byteArrayOutputStream.toByteArray(), headers, HttpStatus.OK);
    }

    private ResponseEntity<byte[]> zipPdfBriefReport(List<FileResponse> pdfFileList, Map<Integer, String> briefReportMap) {
        //通过ZipOutputStream定义要写入的对象
        ZipOutputStream zos = null;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            int i = 0;
            zos = new ZipOutputStream(byteArrayOutputStream);
            for (FileResponse fileResponse : pdfFileList) {
                URL url = new URL(fileResponse.getUrl());
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
                conn.setConnectTimeout(3 * 1000);
                final ByteArrayOutputStream output = new ByteArrayOutputStream();
                IOUtils.copy(conn.getInputStream(), output);
                zos.putNextEntry(new ZipEntry(briefReportMap.get(i) + "-" + (i + 1) + ".pdf"));
                byte[] excelStream = output.toByteArray();
                zos.write(excelStream);
                i++;
                zos.closeEntry();
                zos.flush();

            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        } finally {
            try {
                assert zos != null;
                zos.flush();
                zos.close();
                byteArrayOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_STREAM_JSON);
        String fileName = "简报.zip";
        headers.setContentDispositionFormData("attachment", new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
        return new ResponseEntity<>(byteArrayOutputStream.toByteArray(), headers, HttpStatus.OK);
    }
}
